(圖源:Tim Pope's twitter)
這篇文章會介紹一個VSCodeVim官方文件(v1.23.0以前)並沒有詳述到的實用技巧。
技巧會「實用」,不是因為它很炫、很艱深或者是很罕見,而是他會幫助我們解決特定場景下的問題。以這篇文章所介紹的技巧為例,它會讓我們的操作與命令組合更順手。
事實上,官方文件沒有詳述的命令或設定很多,但未必每個都實用,或是每個都能幫助我們建立起操作的思維與觀念。所以在挑選它們介紹的時候作者還是有一定原則的。
首先,還是讓我們先介紹一下相關原生Vim命令的基本操作,再來看一下情境。
想像一下,目前我們有一段這樣長短不均的文字,我們要同時對第二欄中每一行的user
文字都改成command
。
| Name | Type | Command(s) |
| -----------------------| ------- | ----------------------------- |
| Open Project | user | `vsce-script.openProject` |
| Create Script Project | user | `vsce-script.createProject` |
如果是在Vim裡,這時我們可以使用「Ctrl
+v
」命令,進入Visual Block模式,此時再按j
往下可以連續選取到第二行,這時我們按e
可以同時選取到這兩個字,之後我們按c
可以修改它,輸入command字樣後,按兩次Esc
,就可以完成動作。
上面這是在Vim裡對Visual Block模式的基本操作,讓我們來看在該模式時會遇到的一些問題。
上面這是比較理想的狀況,現在我們可能遇到編輯長短不均的多行文字的情境,如下所示:
AAAAAAAAAAA
BBBBB
CCCCCCCCCCCC
DDDD
EEEEEEEE
在這種情境下我們可能因此無法完成某些操作。
此時,我們編輯塊狀的文字時可能會遇到游標移動不到行尾的狀況。
遇到這種情境時,其中一種可行的解決辦法是在Vim裡啟用virtualedit=block
的選項,在命令列模式裡輸入下面這行:
啟用後,同樣的操作就可以選取至行尾。
可惜,在VSCodeVim裡並沒有直接實現該選項,這是一個Github上Open的Issue,會選擇不實現這個選項跟VS Code的環境有關。
但VSCodeVim沒有實現該選項,並不意味著我們因此完全無法編輯多行長短不均的文字。讓我們先試著用底下技巧來解決需求。
在此之前,《Practical Vim》在技巧26中提出了一個組合命令的技巧,可以在Vim裡面解決在結尾追加文字的需求。
AAAAAAAAAAA
BBBBB
CCCCCCCCCCCC
DDDD
EEEEEEEE
首先,讓我們先進入Visual Block,並使用j
往下選取到最後一行。
之後,使用$
命令,這會讓游標移動到結尾。因為是在Visual Block模式裡,每一列都會選取到文字最後面。
最後,我們要進行編輯,此時可以使用A
(append),讓游標進入插入模式。
(註:若是在普通模式使用A
,則會直接讓游標移到尾端,並進入插入模式。)
此時,我們再輸入要追加的文字,此處我們輸入追加的文字「123」,再按「Esc」離開,就可以完成文字的追加。
完整的操作如下所示:
好,剛才的操作是筆者在MacOS裡的Vim完成的,同樣的技巧也可以在VSCodeVim中使用,讓我們在VS Code裡面操作看看。
在VS Code裡,使用同樣技巧追加文字時,多行文字會立刻出現,不會像Vim裡按Esc後才全部顯示。在這方面的UX好些。
假如,我們想在移動多行後的中間插入文字,一樣可以如法炮製,使用A
命令。
不過,在VSCodeVim裡我們也同樣跟Vim一樣有著先天上的限制。是什麼樣的限制呢?
1. 在Visual Block模式中無法直接使用i
(insert),a
(append)命令
在Vim的Visual模式中,我們的i
, a
命令是保留給Text Object的。假如我們要選中一個文字(word),我們可以使用viw
來選取它。作為Text Object來使用時,i
的語意是inner,a
是arround。
這個設計有其理由,但也因此,在Visual Block中我們無法游標移動到哪裡,就使用i
、a
,得改用I
或A
命令,這樣有點違反直覺。
大部分人,若沒有看過相關文章,根本不會知道在Visual Block模式插入文字的命令是這樣用的,通常就是直接點擊i
、a
命令後效果不如預期就放棄了。
另外,使用A
命令時要多按一個shift鍵,不如直接按i
來得輕鬆愉快。
2. 選取範圍呈現塊狀,無法很好的與組合命令結合
e
,此時我們可能會預期游標移動到vscode
和lib
的尾端。可惜並不會這樣,游標選去的可視範圍是塊狀的。f
(find)命令時會遇到的狀況,在下面的例子中,因為第一欄有一個列長度不一樣,我們在使用f|
命令時,就無法在第三列精準的選中|
字元,同時對其進行操作。3. 受限於組合命令上的限制,無法進行最有效率的操作
由於組合命令上的限制,我們在「tip26」裡進入Visual Block後得先使用$
,再使用A
。$
是少數可以在Visual Block模式中正常使用的命令。
若普通模式操作單行文字,只要使用A(append),就可以移動到行尾,並進入到插入模式。上面的方式讓我們在相關操作時多打了shift
、4
兩個鍵。
在上面,我們的操作受到了些限制。在VSCodeVim裡面,我們其實可以使用
cmd
+ option
+ down
」、「cmd
+ option
+ up
」ctrl
+ alt
+ down
」、「ctrl
+ alt
+ up
」這兩組快捷鍵,往下、上新增一個新的游標。
MacOS的使用者用第一組快捷鍵,Windows使用者使用第二組快捷鍵。
好的,現在讓我們來看一下,怎麼使用這個命令:
(此處僅示範往下追加游標的動作,要往上追加的話將快捷鍵中的方向鍵改成上即可)
在對多行進行操作時,只要是VSCodeVim相關的命令,在普通模式下可以結合次數使用這個命令,幫助我們快速追加多行游標。
下面我們要追加8個游標,所以依序輸入8
、cdm+option+down
,就往下新增八個游標,減少許多重複輸入命令的時間。
好的,介紹以上操作後,進入重頭戲。
透過這幾個命令,我們創造了Multiple Cursors。在筆者也有學習並受益過的《Boost Your Coding Fu With Visual Studio Code and Vim》一書中,有一節「ADD MULTIPLE CURSORS ON CONSECUTIVE LINES」是在處理相同的情境,但裡面介紹的方法其實也還是基於我們這篇文章第三節所介紹的「《Practical Vim》tips26」的,仍然會遇到上面我們所提到的3個狀況。
現在就讓我們來看一下這個命令能不能解決上面3種我們在Visual Block模式組合命令時遇到的狀況。
此處在移動游標的過程中使用i
和a
都是可以的,上面我們示範在多游標模式中使用i
命令的操作。
e
,此時游標如預期移動到vscode
和lib
的尾端。f
(find)命令選取不規則長度多行內的指定字元可以看到,兩種命令組合都順利運作,符合我們的預期。
剛才有提到最自然的移動方式其實是直接使用A
命令將游標移到尾端並進入插入模式,讓我們動手嘗試一下:
完成後,我們可以看到,多個游標順利的移到尾端並進入插入模式,每次修改所需的$
命令至此完全被省略了。
透過這組命令,我們可以的操作毫不拖泥帶水。前面在組合命令時困擾不復存在,組合各個命令非常的輕鬆。
在背後,VSCodeVim提供的這兩組命令本身是基於VS Code內建的「Add Curosr Above」與「Add Cursor Below」兩個命令實現的。
也因此,透過這個例子直接地顯示出:
「在VS Code裡,結合Vim的思維,搭配適當的VS Code命令,我們可以找出相較Vim預設命令與技巧更有效率的組合。」
這並不是說,VS Code的命令就一定比較好。這需要在各個情境下、經過實際驗證後,我們才會知道哪些合適的命令可以被很好的組合在一起。
上面就是一個很好的例子。
官方文件和官方的Roadmap目前還都沒有提到這個命令,也許它只被一部分的使用者所使用吧!
至於專案貢獻者們與維護者是怎麼知道有這個技巧的?是因為10000顆星星以上專案的開發者們也跟他很熟,所以有人跟他說有這個技巧可以用。然後他好棒棒,每個人都要替他拍手手嗎?
筆者當然不走上面這個路線,還是套句老話:
「只要你懂XX,XX就會幫你」。
緣份到了,就知道了(認真講一下,這是自身經驗呦)。
這兩組命令的設計其實是基於VS Code內建的多游標快捷鍵,只是VSCodeVim將這兩個預設的快捷鍵重新綁定,並將其轉為的其中一個命令或者說動作(Action)。也因此,它可以搭配數字執行,避免重複。
也就是說,如果讀者本身就熟悉VS Code的內建快捷鍵,是很容易觸類旁通,進而發現有這個命令的,只是說不見得會想到可以在與Visual Block模式相關的再把他跟命令組合,因為少了使用情境。
如果是從Vim過來使用VSCodeVim的使用者,可能不見得馬上知道有這個快捷鍵。但如果他們不心生排斥, 等到熟悉VS Code後,他們更有潛力挖掘出更有效率的組合方法。因為客觀來看,Vim的學習曲線比VS Code更高。
這個技巧並沒有在《Visual Studio Code實用指南》中介紹。雖然它可以解決此一情境的問題,並且算是同類方法裡的Best Practice,但對使用者而言,還是有可能自行發現這個命令的,只是對一些細節不見得那麼清楚。筆者認為最重要還是選用方法的觀念與經驗。而不是只學一些tips。所以在能表現連貫的思想並漸進的交代相關內容的前提下,這個tips的內容被介紹的優先度就不是最高的。
學習Vim跟VS Code的相關資源實在太多,這會造成一個問題,學習者很容易就迷失在細節裡。沒辦法有順序的建立起操作的習慣與思維。我認為好的書是會選擇性的減少某些題材的論述的,儘管這可能讓他的某些內容看起來變得簡單。
關於這類技巧,之所以會用「官方文件沒有詳述」到這類語句是因為,客觀來講,這技巧應該是被當年貢獻這些程式碼的人所熟知的。它並不新,但是對不知道的使用者來講,是有一段資訊落差。
有些難的東西付出多一點學習成本可以學到,但對於沒有相關資訊的素材我們是無法直接透過文件學習並了解它的。
至於為什麼開發者們的文件不寫詳細一點呢?就筆者實際的例子,寫文件本身非常費時也耗腦力,常常一個自己熟知的觀念或操作,為了轉成文字介紹給別人或初學者就要花老半天時間。開源的專案大多都是下班後進行開發的,要再寫文件時間更是缺少。
除此之外,使用者的積極程度也會很大的影響專案的開發者或維護者的心情。當多數人都是在「take」而非「give」時,願意分享的心情就會跟著低落。除非再有新的貢獻者,在他們的熱情尚未全部燃盡前提交出新的文件的Pull Request。不然這些隱藏的開發功能是不會自動出現在文件上的。
「儘管他們什麼都知道,但他們有什麼理由要為此而加班?」
好吧,沒有掌握所有這些技巧的我們,不必心急。雖然了解這類技巧會有一定幫助,但也不用因為不知道所有技巧而著急。能夠有正確的觀念與學習方向,逐步解決手頭上的問題就已經是很好的步調了。